From 93e6c4731dfb17687cde9a867717a0374b3a68f7 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 23 Nov 2009 06:54:03 +0000 Subject: [PATCH] libxenlight: implement support for pv guests This patch makes pv guest work correctly with libxenlight. It also implements support for vfb and vkbd, starting qemu in xenpv mode. Both xenconsole and qemu are supported as console backends. Signed-off-by: Stefano Stabellini --- tools/libxl/libxl.c | 340 +++++++++++++++++++++++++++++------ tools/libxl/libxl.h | 53 +++++- tools/libxl/libxl_device.c | 27 ++- tools/libxl/libxl_dom.c | 41 +++-- tools/libxl/libxl_internal.h | 12 +- tools/libxl/xl.c | 281 ++++++++++++++++++++++------- 6 files changed, 612 insertions(+), 142 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 45766fb3b2..1fd7669093 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -23,6 +23,8 @@ #include #include #include /* for write, unlink and close */ +#include +#include #include "libxl.h" #include "libxl_utils.h" #include "libxl_internal.h" @@ -156,7 +158,6 @@ retry_transaction: xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, strlen(info->name)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/image/ostype", vm_path), "hvm", strlen("hvm")); libxl_xs_writev(ctx, t, dom_path, info->xsdata); libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), info->platformdata); @@ -169,24 +170,33 @@ retry_transaction: return 0; } -int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid) +libxl_domain_build_state *libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid) { - libxl_domain_build_state state; + libxl_domain_build_state *state = (libxl_domain_build_state *) libxl_calloc(ctx, 1, sizeof(libxl_domain_build_state)); char **vments = NULL, **localents = NULL; - memset(&state, '\0', sizeof(state)); - - build_pre(ctx, domid, info, &state); + build_pre(ctx, domid, info, state); if (info->hvm) { - build_hvm(ctx, domid, info, &state); - vments = libxl_calloc(ctx, 4, sizeof(char *)); + build_hvm(ctx, domid, info, state); + vments = libxl_calloc(ctx, 5, sizeof(char *)); vments[0] = libxl_sprintf(ctx, "rtc/timeoffset"); vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""); + vments[2] = libxl_sprintf(ctx, "image/ostype"); + vments[3] = libxl_sprintf(ctx, "hvm"); } else { - build_pv(ctx, domid, info, &state); + build_pv(ctx, domid, info, state); + vments = libxl_calloc(ctx, 9, sizeof(char *)); + vments[0] = libxl_sprintf(ctx, "image/ostype"); + vments[1] = libxl_sprintf(ctx, "linux"); + vments[2] = libxl_sprintf(ctx, "image/kernel"); + vments[3] = libxl_sprintf(ctx, info->kernel); + vments[4] = libxl_sprintf(ctx, "image/ramdisk"); + vments[5] = libxl_sprintf(ctx, info->u.pv.ramdisk); + vments[6] = libxl_sprintf(ctx, "image/cmdline"); + vments[7] = libxl_sprintf(ctx, info->u.pv.cmdline); } - build_post(ctx, domid, info, &state, vments, localents); - return 0; + build_post(ctx, domid, info, state, vments, localents); + return state; } int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info, @@ -414,13 +424,6 @@ static char ** libxl_build_device_model_args(struct libxl_ctx *ctx, flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-domain-name")); flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->dom_name)); } - if (info->videoram) { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-videoram")); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->videoram)); - } - if (info->stdvga) { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-std-vga")); - } if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) { flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vnc")); if (info->vncdisplay) { @@ -459,38 +462,47 @@ static char ** libxl_build_device_model_args(struct libxl_ctx *ctx, flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-serial")); flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->serial)); } - if (info->boot) { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-boot")); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->boot)); - } - if (info->usb) { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usb")); - if (info->usbdevice) { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usbdevice")); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->usbdevice)); + if (info->type == XENFV) { + if (info->videoram) { + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-videoram")); + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->videoram)); } - } - if (info->apic) { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-acpi")); - } - if (info->extra) { - int i = 0; - while (info->extra[i] != NULL) { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->extra[i])); + if (info->stdvga) { + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-std-vga")); } - } - for (i = 0; i < num_vifs; i++) { - if (vifs[i].nictype == NICTYPE_IOEMU) { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net")); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", - vifs[i].devid, vifs[i].smac, vifs[i].model)); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net")); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s", - vifs[i].devid, vifs[i].ifname, vifs[i].bridge)); + + if (info->boot) { + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-boot")); + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->boot)); + } + if (info->usb) { + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usb")); + if (info->usbdevice) { + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usbdevice")); + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->usbdevice)); + } + } + if (info->apic) { + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-acpi")); + } + for (i = 0; i < num_vifs; i++) { + if (vifs[i].nictype == NICTYPE_IOEMU) { + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net")); + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", + vifs[i].devid, vifs[i].smac, vifs[i].model)); + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net")); + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s", + vifs[i].devid, vifs[i].ifname, vifs[i].bridge)); + } } } + for (i = 0; info->extra && info->extra[i] != NULL; i++) + flexarray_set(dm_args, num++, info->extra[i]); flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-M")); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenfv")); + if (info->type == XENPV) + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenpv")); + else + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenfv")); flexarray_set(dm_args, num++, NULL); return (char **) flexarray_contents(dm_args); @@ -579,7 +591,7 @@ int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_di case PHYSTYPE_PHY: { int major, minor; - device_disk_major_minor(disk->virtpath, &major, &minor); + device_physdisk_major_minor(disk->physpath, &major, &minor); flexarray_set(back, boffset++, libxl_sprintf(ctx, "physical-device")); flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor)); @@ -604,6 +616,8 @@ int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_di flexarray_set(back, boffset++, libxl_sprintf(ctx, "1")); flexarray_set(back, boffset++, libxl_sprintf(ctx, "removable")); flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", (disk->unpluggable) ? 1 : 0)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "bootable")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); flexarray_set(back, boffset++, libxl_sprintf(ctx, "state")); flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev")); @@ -716,9 +730,125 @@ int libxl_device_nic_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) } /******************************************************************************/ -int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid) +int libxl_device_console_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_console *console) { - return ERROR_NI; + flexarray_t *front; + flexarray_t *back; + unsigned int boffset = 0; + unsigned int foffset = 0; + libxl_device device; + + if (console->build_state) { + xs_transaction_t t; + char **ents = (char **) libxl_calloc(ctx, 9, sizeof(char *)); + ents[0] = libxl_sprintf(ctx, "console/port"); + ents[1] = libxl_sprintf(ctx, "%"PRIu32, console->build_state->console_port); + ents[2] = libxl_sprintf(ctx, "console/ring-ref"); + ents[3] = libxl_sprintf(ctx, "%lu", console->build_state->console_mfn); + ents[4] = libxl_sprintf(ctx, "console/limit"); + ents[5] = libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT); + ents[6] = libxl_sprintf(ctx, "console/type"); + if (console->constype == CONSTYPE_XENCONSOLED) + ents[7] = "xenconsoled"; + else + ents[7] = "ioemu"; +retry_transaction: + t = xs_transaction_start(ctx->xsh); + libxl_xs_writev(ctx, t, xs_get_domain_path(ctx->xsh, console->domid), ents); + if (!xs_transaction_end(ctx->xsh, t, 0)) + if (errno == EAGAIN) + goto retry_transaction; + } + + front = flexarray_make(16, 1); + if (!front) + return ERROR_NOMEM; + back = flexarray_make(16, 1); + if (!back) + return ERROR_NOMEM; + + device.backend_devid = console->devid; + device.backend_domid = console->backend_domid; + device.backend_kind = DEVICE_CONSOLE; + device.devid = console->devid; + device.domid = console->domid; + device.kind = DEVICE_CONSOLE; + + flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", console->domid)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "online")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "1")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "state")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "domain")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", libxl_domid_to_name(ctx, domid))); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "protocol")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, LIBXL_XENCONSOLE_PROTOCOL)); + + flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id")); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", console->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "state")); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "limit")); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT)); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol")); + flexarray_set(front, foffset++, libxl_sprintf(ctx, LIBXL_XENCONSOLE_PROTOCOL)); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "type")); + if (console->constype == CONSTYPE_XENCONSOLED) + flexarray_set(front, foffset++, libxl_sprintf(ctx, "xenconsoled")); + else + flexarray_set(front, foffset++, libxl_sprintf(ctx, "ioemu")); + + libxl_device_generic_add(ctx, &device, + libxl_xs_kvs_of_flexarray(ctx, back, boffset), + libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + + + return 0; +} + +/******************************************************************************/ +int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb) +{ + flexarray_t *front; + flexarray_t *back; + unsigned int boffset = 0; + unsigned int foffset = 0; + libxl_device device; + + front = flexarray_make(16, 1); + if (!front) + return ERROR_NOMEM; + back = flexarray_make(16, 1); + if (!back) + return ERROR_NOMEM; + + device.backend_devid = vkb->devid; + device.backend_domid = vkb->backend_domid; + device.backend_kind = DEVICE_VKBD; + device.devid = vkb->devid; + device.domid = vkb->domid; + device.kind = DEVICE_VKBD; + + flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vkb->domid)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "online")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "1")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "state")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "domain")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", libxl_domid_to_name(ctx, domid))); + + flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id")); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", vkb->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "state")); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + + libxl_device_generic_add(ctx, &device, + libxl_xs_kvs_of_flexarray(ctx, back, boffset), + libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + + return 0; } int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) @@ -732,9 +862,119 @@ int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) } /******************************************************************************/ -int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid) +static int libxl_build_xenpv_qemu_args(struct libxl_ctx *ctx, + libxl_device_vfb *vfb, + int num_console, + libxl_device_console *console, + libxl_device_model_info *info) { + int i = 0, j = 0, num = 0; + memset(info, 0x00, sizeof(libxl_device_model_info)); + + info->vnc = vfb->vnc; + if (vfb->vnclisten) + info->vnclisten = libxl_sprintf(ctx, "%s", vfb->vnclisten); + info->vncdisplay = vfb->vncdisplay; + info->vncunused = vfb->vncunused; + if (vfb->keymap) + info->keymap = libxl_sprintf(ctx, "%s", vfb->keymap); + info->sdl = vfb->sdl; + info->opengl = vfb->opengl; + for (i = 0; i < num_console; i++) { + if (console->constype == CONSTYPE_IOEMU) + num++; + } + if (num > 0) { + info->serial = "pty"; + num--; + } + if (num > 0) { + info->extra = (char **) libxl_calloc(ctx, num * 2 + 1, sizeof(char *)); + for (j = 0; j < num * 2; j = j + 2) { + info->extra[j] = "-serial"; + info->extra[j + 1] = "pty"; + } + info->extra[j] = NULL; + } + info->domid = vfb->domid; + info->dom_name = libxl_domid_to_name(ctx, vfb->domid); + info->device_model = "/usr/lib/xen/bin/qemu-dm"; + info->type = XENPV; + return 0; +} + +int libxl_create_xenpv_qemu(struct libxl_ctx *ctx, libxl_device_vfb *vfb, + int num_console, libxl_device_console *console) { - return ERROR_NI; + libxl_device_model_info info; + + libxl_build_xenpv_qemu_args(ctx, vfb, num_console, console, &info); + libxl_create_device_model(ctx, &info, NULL, 0); + return 0; +} + +int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb) +{ + flexarray_t *front; + flexarray_t *back; + unsigned int boffset = 0; + unsigned int foffset = 0; + libxl_device device; + + front = flexarray_make(16, 1); + if (!front) + return ERROR_NOMEM; + back = flexarray_make(16, 1); + if (!back) + return ERROR_NOMEM; + + device.backend_devid = vfb->devid; + device.backend_domid = vfb->backend_domid; + device.backend_kind = DEVICE_VFB; + device.devid = vfb->devid; + device.domid = vfb->domid; + device.kind = DEVICE_VFB; + + flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->domid)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "online")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "1")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "state")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "domain")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", libxl_domid_to_name(ctx, domid))); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "vnc")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vnc)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "vnclisten")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", vfb->vnclisten)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "vncdisplay")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncdisplay)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "vncunused")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncunused)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "sdl")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->sdl)); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "opengl")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->opengl)); + if (vfb->xauthority) { + flexarray_set(back, boffset++, libxl_sprintf(ctx, "xauthority")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", vfb->xauthority)); + } + if (vfb->display) { + flexarray_set(back, boffset++, libxl_sprintf(ctx, "display")); + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", vfb->display)); + } + + flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id")); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", vfb->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "state")); + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + + libxl_device_generic_add(ctx, &device, + libxl_xs_kvs_of_flexarray(ctx, back, boffset), + libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + flexarray_free(front); + flexarray_free(back); + + return 0; } int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 0241a0ea0b..0c6f168fee 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -76,19 +76,28 @@ typedef struct { struct { const char *cmdline; const char *ramdisk; + const char *features; } pv; } u; } libxl_domain_build_info; +typedef struct libxl_domain_build_state_ libxl_domain_build_state; + typedef struct { int flags; int (*suspend_callback)(void *, int); } libxl_domain_suspend_info; +typedef enum { + XENFV, + XENPV, +} libxl_qemu_machine_type; + typedef struct { int domid; char *dom_name; char *device_model; + libxl_qemu_machine_type type; int videoram; /* size of the videoram in MB */ bool stdvga; /* stdvga enabled or disabled */ bool vnc; /* vnc enabled or disabled */ @@ -108,6 +117,40 @@ typedef struct { /* Network is missing */ } libxl_device_model_info; +typedef struct { + uint32_t backend_domid; + uint32_t domid; + int devid; + bool vnc; /* vnc enabled or disabled */ + char *vnclisten; /* address:port that should be listened on for the VNC server if vnc is set */ + int vncdisplay; /* set VNC display number */ + bool vncunused; /* try to find an unused port for the VNC server */ + char *keymap; /* set keyboard layout, default is en-us keyboard */ + bool sdl; /* sdl enabled or disabled */ + bool opengl; /* opengl enabled or disabled (if enabled requires sdl enabled) */ + char *display; + char *xauthority; +} libxl_device_vfb; + +typedef struct { + uint32_t backend_domid; + uint32_t domid; + int devid; +} libxl_device_vkb; + +typedef enum { + CONSTYPE_XENCONSOLED, + CONSTYPE_IOEMU, +} libxl_console_constype; + +typedef struct { + uint32_t backend_domid; + uint32_t domid; + int devid; + libxl_console_constype constype; + libxl_domain_build_state *build_state; +} libxl_device_console; + typedef enum { PHYSTYPE_QCOW, PHYSTYPE_QCOW2, @@ -179,7 +222,7 @@ int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, vo /* domain related functions */ int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid); -int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid); +libxl_domain_build_state *libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid); int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, int fd); int libxl_domain_suspend(struct libxl_ctx *ctx, libxl_domain_suspend_info *info, @@ -196,6 +239,8 @@ xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain); int libxl_create_device_model(struct libxl_ctx *ctx, libxl_device_model_info *info, libxl_device_nic *vifs, int num_vifs); +int libxl_create_xenpv_qemu(struct libxl_ctx *ctx, libxl_device_vfb *vfb, + int num_console, libxl_device_console *console); int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk); int libxl_device_disk_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); @@ -205,11 +250,13 @@ int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_nic int libxl_device_nic_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); int libxl_device_nic_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid); -int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid); +int libxl_device_console_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_console *console); + +int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb); int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid); -int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid); +int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb); int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); int libxl_device_vfb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid); diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index 1355314a96..eee0a40e0d 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -19,6 +19,9 @@ #include "libxl.h" #include "libxl_internal.h" #include /* for struct timeval */ +#include +#include +#include char *string_of_kinds[] = { [DEVICE_VIF] = "vif", @@ -27,6 +30,7 @@ char *string_of_kinds[] = { [DEVICE_PCI] = "pci", [DEVICE_VFB] = "vfb", [DEVICE_VKBD] = "vkbd", + [DEVICE_CONSOLE] = "console", }; int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device, @@ -118,7 +122,17 @@ char *device_disk_backend_type_of_phystype(libxl_disk_phystype phystype) } } -int device_disk_major_minor(char *virtpath, int *major, int *minor) +int device_physdisk_major_minor(char *physpath, int *major, int *minor) +{ + struct stat buf; + if (stat(physpath, &buf) < 0) + return -1; + *major = major(buf.st_rdev); + *minor = minor(buf.st_rdev); + return 0; +} + +int device_virtdisk_major_minor(char *virtpath, int *major, int *minor) { if (strstr(virtpath, "sd") == virtpath) { return -1; @@ -146,9 +160,14 @@ int device_disk_dev_number(char *virtpath) int majors_table[] = { 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 }; int major, minor; - if (device_disk_major_minor(virtpath, &major, &minor)) - return -1; - return majors_table[major / 2] * 256 + (64 * (major % 2)) + minor; + if (strstr(virtpath, "hd") == virtpath) { + if (device_virtdisk_major_minor(virtpath, &major, &minor)) + return -1; + return majors_table[major / 2] * 256 + (64 * (major % 2)) + minor; + } else if (strstr(virtpath, "xvd") == virtpath) { + return (202 << 8) + ((virtpath[3] - 'a') << 4) + (virtpath[4] ? (virtpath[4] - '0') : 0); + } + return -1; } int libxl_device_destroy(struct libxl_ctx *ctx, char *be_path, int force) diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 92e13242f2..a98daee19b 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -15,8 +15,11 @@ #include "libxl.h" #include "libxl_internal.h" +#include #include #include +#include +#include #include #include /* for struct timeval */ #include /* for sleep(2) */ @@ -37,7 +40,6 @@ int is_hvm(struct libxl_ctx *ctx, uint32_t domid) int build_pre(struct libxl_ctx *ctx, uint32_t domid, libxl_domain_build_info *info, libxl_domain_build_state *state) { - unsigned long shadow; if (info->timer_mode != -1) xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_TIMER_MODE, (unsigned long) info->timer_mode); @@ -48,8 +50,12 @@ int build_pre(struct libxl_ctx *ctx, uint32_t domid, xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus); xc_domain_setmaxmem(ctx->xch, domid, info->max_memkb + info->video_memkb); xc_domain_set_memmap_limit(ctx->xch, domid, info->max_memkb); - shadow = (info->shadow_memkb + 1023) / 1024; - xc_shadow_control(ctx->xch, domid, XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL); + + if (info->hvm) { + unsigned long shadow; + shadow = (info->shadow_memkb + 1023) / 1024; + xc_shadow_control(ctx->xch, domid, XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL); + } state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); @@ -64,7 +70,7 @@ int build_post(struct libxl_ctx *ctx, uint32_t domid, xs_transaction_t t; char **ents; - ents = libxl_calloc(ctx, 6 * 2, sizeof(char *)); + ents = libxl_calloc(ctx, 10 * 2, sizeof(char *)); ents[0] = libxl_sprintf(ctx, "memory/static-max"); ents[1] = libxl_sprintf(ctx, "%d", info->max_memkb); ents[2] = libxl_sprintf(ctx, "memory/target"); @@ -95,14 +101,25 @@ retry_transaction: int build_pv(struct libxl_ctx *ctx, uint32_t domid, libxl_domain_build_info *info, libxl_domain_build_state *state) { -#if 0 /* unused variables */ - int mem_target_kib = info->max_memkb; - char *domid_str = libxl_sprintf(ctx, "%d", domid); - char *memsize_str = libxl_sprintf(ctx, "%d", mem_target_kib / 1024); - char *store_port_str = libxl_sprintf(ctx, "%d", state->store_port); - char *console_port_str = libxl_sprintf(ctx, "%d", state->console_port); -#endif - return ERROR_NI; + struct xc_dom_image *dom; + int ret; + int flags = 0; + + dom = xc_dom_allocate(info->u.pv.cmdline, info->u.pv.features); + if (!dom) { + XL_LOG(ctx, XL_LOG_ERROR, "xc_dom_allocate failed: %d", dom); + return -1; + } + if ((ret = xc_dom_linux_build(ctx->xch, dom, domid, info->max_memkb / 1024, + info->kernel, info->u.pv.ramdisk, flags, + state->store_port, &state->store_mfn, + state->console_port, &state->console_mfn)) != 0) { + xc_dom_release(dom); + XL_LOG(ctx, XL_LOG_ERROR, "xc_dom_linux_build failed: %d", ret); + return -2; + } + xc_dom_release(dom); + return 0; } int build_hvm(struct libxl_ctx *ctx, uint32_t domid, diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 4bb713fc81..d6835be53e 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -15,7 +15,7 @@ */ #ifndef LIBXL_INTERNAL_H -# define LIBXL_INTERNAL_H +#define LIBXL_INTERNAL_H #include #include @@ -28,6 +28,8 @@ #include "libxl_utils.h" #define LIBXL_DESTROY_TIMEOUT 10 +#define LIBXL_XENCONSOLE_LIMIT 1048576 +#define LIBXL_XENCONSOLE_PROTOCOL "vt100" #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) @@ -47,12 +49,12 @@ void xl_log(struct libxl_ctx *ctx, int loglevel, const char *file, int line, const char *func, char *fmt, ...); -typedef struct { +struct libxl_domain_build_state_ { uint32_t store_port; unsigned long store_mfn; uint32_t console_port; unsigned long console_mfn; -} libxl_domain_build_state; +}; typedef enum { DEVICE_VIF, @@ -61,6 +63,7 @@ typedef enum { DEVICE_PCI, DEVICE_VFB, DEVICE_VKBD, + DEVICE_CONSOLE, } libxl_device_kinds; typedef struct { @@ -119,7 +122,8 @@ int core_suspend(struct libxl_ctx *ctx, uint32_t domid, int fd, int hvm, int liv char *device_disk_backend_type_of_phystype(libxl_disk_phystype phystype); char *device_disk_string_of_phystype(libxl_disk_phystype phystype); -int device_disk_major_minor(char *virtpath, int *major, int *minor); +int device_physdisk_major_minor(char *physpath, int *major, int *minor); +int device_virtdisk_major_minor(char *virtpath, int *major, int *minor); int device_disk_dev_number(char *virtpath); int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device, diff --git a/tools/libxl/xl.c b/tools/libxl/xl.c index 4395268b00..3b735ec78a 100644 --- a/tools/libxl/xl.c +++ b/tools/libxl/xl.c @@ -42,10 +42,14 @@ static void printf_info(libxl_domain_create_info *c_info, int num_vifs, libxl_device_pci *pcidevs, int num_pcidevs, + libxl_device_vfb *vfbs, + int num_vfbs, + libxl_device_vkb *vkb, + int num_vkbs, libxl_device_model_info *dm_info) { int i; - char uuid_str[18]; + char uuid_str[37]; printf("*** domain_create_info ***\n"); printf("hvm: %d\n", c_info->hvm); printf("hap: %d\n", c_info->hap); @@ -69,12 +73,12 @@ static void printf_info(libxl_domain_create_info *c_info, printf("vpt_align: %d\n", b_info->vpt_align); printf("max_vcpus: %d\n", b_info->max_vcpus); printf("max_memkb: %d\n", b_info->max_memkb); - printf("video_memkb: %d\n", b_info->video_memkb); - printf("shadow_memkb: %d\n", b_info->shadow_memkb); printf("kernel: %s\n", b_info->kernel); printf("hvm: %d\n", b_info->hvm); - if (b_info->hvm) { + if (c_info->hvm) { + printf("video_memkb: %d\n", b_info->video_memkb); + printf("shadow_memkb: %d\n", b_info->shadow_memkb); printf(" pae: %d\n", b_info->u.hvm.pae); printf(" apic: %d\n", b_info->u.hvm.apic); printf(" acpi: %d\n", b_info->u.hvm.acpi); @@ -114,25 +118,43 @@ static void printf_info(libxl_domain_create_info *c_info, printf("opts msitranslate %d power_mgmt %d\n", pcidevs[i].msitranslate, pcidevs[i].power_mgmt); } - printf("\n\n\n*** device_model_info ***\n"); - printf("domid: %d\n", dm_info->domid); - printf("dom_name: %s\n", dm_info->dom_name); - printf("device_model: %s\n", dm_info->device_model); - printf("videoram: %d\n", dm_info->videoram); - printf("stdvga: %d\n", dm_info->stdvga); - printf("vnc: %d\n", dm_info->vnc); - printf("vnclisten: %s\n", dm_info->vnclisten); - printf("vncdisplay: %d\n", dm_info->vncdisplay); - printf("vncunused: %d\n", dm_info->vncunused); - printf("keymap: %s\n", dm_info->keymap); - printf("sdl: %d\n", dm_info->sdl); - printf("opengl: %d\n", dm_info->opengl); - printf("nographic: %d\n", dm_info->nographic); - printf("serial: %s\n", dm_info->serial); - printf("boot: %s\n", dm_info->boot); - printf("usb: %d\n", dm_info->usb); - printf("usbdevice: %s\n", dm_info->usbdevice); - printf("apic: %d\n", dm_info->apic); + for (i = 0; i < num_vfbs; i++) { + printf("\n\n\n*** vfbs_info: %d ***\n", i); + printf("backend_domid %d\n", vfbs[i].backend_domid); + printf("domid %d\n", vfbs[i].domid); + printf("devid %d\n", vfbs[i].devid); + printf("vnc: %d\n", vfbs[i].vnc); + printf("vnclisten: %s\n", vfbs[i].vnclisten); + printf("vncdisplay: %d\n", vfbs[i].vncdisplay); + printf("vncunused: %d\n", vfbs[i].vncunused); + printf("keymap: %s\n", vfbs[i].keymap); + printf("sdl: %d\n", vfbs[i].sdl); + printf("opengl: %d\n", vfbs[i].opengl); + printf("display: %s\n", vfbs[i].display); + printf("xauthority: %s\n", vfbs[i].xauthority); + } + + if (c_info->hvm) { + printf("\n\n\n*** device_model_info ***\n"); + printf("domid: %d\n", dm_info->domid); + printf("dom_name: %s\n", dm_info->dom_name); + printf("device_model: %s\n", dm_info->device_model); + printf("videoram: %d\n", dm_info->videoram); + printf("stdvga: %d\n", dm_info->stdvga); + printf("vnc: %d\n", dm_info->vnc); + printf("vnclisten: %s\n", dm_info->vnclisten); + printf("vncdisplay: %d\n", dm_info->vncdisplay); + printf("vncunused: %d\n", dm_info->vncunused); + printf("keymap: %s\n", dm_info->keymap); + printf("sdl: %d\n", dm_info->sdl); + printf("opengl: %d\n", dm_info->opengl); + printf("nographic: %d\n", dm_info->nographic); + printf("serial: %s\n", dm_info->serial); + printf("boot: %s\n", dm_info->boot); + printf("usb: %d\n", dm_info->usb); + printf("usbdevice: %s\n", dm_info->usbdevice); + printf("apic: %d\n", dm_info->apic); + } } static char* compat_config_file(const char *filename) @@ -208,10 +230,10 @@ void init_build_info(libxl_domain_build_info *b_info, libxl_domain_create_info * b_info->vpt_align = -1; b_info->max_vcpus = 1; b_info->max_memkb = 32 * 1024; - b_info->shadow_memkb = libxl_get_required_shadow_memory(b_info->max_memkb, b_info->max_vcpus); - b_info->video_memkb = 8 * 1024; - b_info->kernel = "/usr/lib/xen/boot/hvmloader"; if (c_info->hvm) { + b_info->shadow_memkb = libxl_get_required_shadow_memory(b_info->max_memkb, b_info->max_vcpus); + b_info->video_memkb = 8 * 1024; + b_info->kernel = "/usr/lib/xen/boot/hvmloader"; b_info->hvm = 1; b_info->u.hvm.pae = 1; b_info->u.hvm.apic = 1; @@ -282,11 +304,54 @@ void disk_info_domid_fixup(libxl_device_disk *disk_info, int domid) disk_info->domid = domid; } +void vfb_info_domid_fixup(libxl_device_vfb *vfb, int domid) +{ + vfb->domid = domid; +} + +void vkb_info_domid_fixup(libxl_device_vkb *vkb, int domid) +{ + vkb->domid = domid; +} + +void console_info_domid_fixup(libxl_device_console *console, int domid) +{ + console->domid = domid; +} + void device_model_info_domid_fixup(libxl_device_model_info *dm_info, int domid) { dm_info->domid = domid; } +void init_vfb_info(libxl_device_vfb *vfb, int dev_num) +{ + memset(vfb, 0x00, sizeof(libxl_device_vfb)); + vfb->devid = dev_num; + vfb->vnc = 1; + vfb->vnclisten = "127.0.0.1"; + vfb->vncdisplay = 0; + vfb->vncunused = 1; + vfb->keymap = NULL; + vfb->sdl = 0; + vfb->opengl = 0; +} + +void init_vkb_info(libxl_device_vkb *vkb, int dev_num) +{ + memset(vkb, 0x00, sizeof(libxl_device_vkb)); + vkb->devid = dev_num; +} + +void init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state) +{ + memset(console, 0x00, sizeof(libxl_device_console)); + console->devid = dev_num; + console->constype = CONSTYPE_XENCONSOLED; + if (state) + console->build_state = state; +} + static void parse_config_file(const char *filename, libxl_domain_create_info *c_info, libxl_domain_build_info *b_info, @@ -296,13 +361,17 @@ static void parse_config_file(const char *filename, int *num_vifs, libxl_device_pci **pcidevs, int *num_pcidevs, + libxl_device_vfb **vfbs, + int *num_vfbs, + libxl_device_vkb **vkbs, + int *num_vkbs, libxl_device_model_info *dm_info) { const char *buf; xen_uuid_t uuid[16]; long l; struct config_t config; - struct config_setting_t *vbds, *nics, *pcis; + struct config_setting_t *vbds, *nics, *pcis, *cvfbs; int pci_power_mgmt = 0; int pci_msitranslate = 1; @@ -367,10 +436,13 @@ static void parse_config_file(const char *filename, if (config_lookup_int (&config, "viridian", &l) == CONFIG_TRUE) b_info->u.hvm.viridian = l; } else { - if (config_lookup_string (&config, "cmdline", &buf) == CONFIG_TRUE) - b_info->u.pv.cmdline = buf; + char *cmdline; + if (config_lookup_string (&config, "root", &buf) == CONFIG_TRUE) { + asprintf(&cmdline, "root=%s", buf); + b_info->u.pv.cmdline = cmdline; + } if (config_lookup_string (&config, "ramdisk", &buf) == CONFIG_TRUE) - b_info->u.pv.ramdisk = buf; + b_info->u.pv.ramdisk = strdup(buf); } if ((vbds = config_lookup (&config, "disk")) != NULL) { @@ -494,6 +566,56 @@ skip: } } + if ((cvfbs = config_lookup (&config, "vfb")) != NULL) { + *num_vfbs = 0; + *num_vkbs = 0; + *vfbs = NULL; + *vkbs = NULL; + while ((buf = config_setting_get_string_elem (cvfbs, *num_vfbs)) != NULL) { + char *buf2 = strdup(buf); + char *p, *p2; + *vfbs = (libxl_device_vfb *) realloc(*vfbs, sizeof(libxl_device_vfb) * ((*num_vfbs) + 1)); + init_vfb_info((*vfbs) + (*num_vfbs), (*num_vfbs)); + + *vkbs = (libxl_device_vkb *) realloc(*vkbs, sizeof(libxl_device_vkb) * ((*num_vkbs) + 1)); + init_vkb_info((*vkbs) + (*num_vkbs), (*num_vkbs)); + + p = strtok(buf2, ","); + if (!p) + goto skip_vfb; + do { + while (*p == ' ') + p++; + if ((p2 = strchr(p, '=')) == NULL) + break; + *p2 = '\0'; + if (!strcmp(p, "vnc")) { + (*vfbs)[*num_vfbs].vnc = atoi(p2 + 1); + } else if (!strcmp(p, "vnclisten")) { + (*vfbs)[*num_vfbs].vnclisten = strdup(p2 + 1); + } else if (!strcmp(p, "vncdisplay")) { + (*vfbs)[*num_vfbs].vncdisplay = atoi(p2 + 1); + } else if (!strcmp(p, "vncunused")) { + (*vfbs)[*num_vfbs].vncunused = atoi(p2 + 1); + } else if (!strcmp(p, "keymap")) { + (*vfbs)[*num_vfbs].keymap = strdup(p2 + 1); + } else if (!strcmp(p, "sdl")) { + (*vfbs)[*num_vfbs].sdl = atoi(p2 + 1); + } else if (!strcmp(p, "opengl")) { + (*vfbs)[*num_vfbs].opengl = atoi(p2 + 1); + } else if (!strcmp(p, "display")) { + (*vfbs)[*num_vfbs].display = strdup(p2 + 1); + } else if (!strcmp(p, "xauthority")) { + (*vfbs)[*num_vfbs].xauthority = strdup(p2 + 1); + } + } while ((p = strtok(NULL, ",")) != NULL); +skip_vfb: + free(buf2); + *num_vfbs = (*num_vfbs) + 1; + *num_vkbs = (*num_vkbs) + 1; + } + } + if (config_lookup_int (&config, "pci_msitranslate", &l) == CONFIG_TRUE) pci_msitranslate = l; @@ -536,38 +658,40 @@ skip_pci: } } - /* init dm from c and b */ - init_dm_info(dm_info, c_info, b_info); - - /* then process config related to dm */ - if (config_lookup_string (&config, "device_model", &buf) == CONFIG_TRUE) - dm_info->device_model = strdup(buf); - if (config_lookup_int (&config, "stdvga", &l) == CONFIG_TRUE) - dm_info->stdvga = l; - if (config_lookup_int (&config, "vnc", &l) == CONFIG_TRUE) - dm_info->vnc = l; - if (config_lookup_string (&config, "vnclisten", &buf) == CONFIG_TRUE) - dm_info->vnclisten = strdup(buf); - if (config_lookup_int (&config, "vncdisplay", &l) == CONFIG_TRUE) - dm_info->vncdisplay = l; - if (config_lookup_int (&config, "vncunused", &l) == CONFIG_TRUE) - dm_info->vncunused = l; - if (config_lookup_string (&config, "keymap", &buf) == CONFIG_TRUE) - dm_info->keymap = strdup(buf); - if (config_lookup_int (&config, "sdl", &l) == CONFIG_TRUE) - dm_info->sdl = l; - if (config_lookup_int (&config, "opengl", &l) == CONFIG_TRUE) - dm_info->opengl = l; - if (config_lookup_int (&config, "nographic", &l) == CONFIG_TRUE) - dm_info->nographic = l; - if (config_lookup_string (&config, "serial", &buf) == CONFIG_TRUE) - dm_info->serial = strdup(buf); - if (config_lookup_string (&config, "boot", &buf) == CONFIG_TRUE) - dm_info->boot = strdup(buf); - if (config_lookup_int (&config, "usb", &l) == CONFIG_TRUE) - dm_info->usb = l; - if (config_lookup_string (&config, "usbdevice", &buf) == CONFIG_TRUE) - dm_info->usbdevice = strdup(buf); + if (c_info->hvm == 1) { + /* init dm from c and b */ + init_dm_info(dm_info, c_info, b_info); + + /* then process config related to dm */ + if (config_lookup_string (&config, "device_model", &buf) == CONFIG_TRUE) + dm_info->device_model = strdup(buf); + if (config_lookup_int (&config, "stdvga", &l) == CONFIG_TRUE) + dm_info->stdvga = l; + if (config_lookup_int (&config, "vnc", &l) == CONFIG_TRUE) + dm_info->vnc = l; + if (config_lookup_string (&config, "vnclisten", &buf) == CONFIG_TRUE) + dm_info->vnclisten = strdup(buf); + if (config_lookup_int (&config, "vncdisplay", &l) == CONFIG_TRUE) + dm_info->vncdisplay = l; + if (config_lookup_int (&config, "vncunused", &l) == CONFIG_TRUE) + dm_info->vncunused = l; + if (config_lookup_string (&config, "keymap", &buf) == CONFIG_TRUE) + dm_info->keymap = strdup(buf); + if (config_lookup_int (&config, "sdl", &l) == CONFIG_TRUE) + dm_info->sdl = l; + if (config_lookup_int (&config, "opengl", &l) == CONFIG_TRUE) + dm_info->opengl = l; + if (config_lookup_int (&config, "nographic", &l) == CONFIG_TRUE) + dm_info->nographic = l; + if (config_lookup_string (&config, "serial", &buf) == CONFIG_TRUE) + dm_info->serial = strdup(buf); + if (config_lookup_string (&config, "boot", &buf) == CONFIG_TRUE) + dm_info->boot = strdup(buf); + if (config_lookup_int (&config, "usb", &l) == CONFIG_TRUE) + dm_info->usb = l; + if (config_lookup_string (&config, "usbdevice", &buf) == CONFIG_TRUE) + dm_info->usbdevice = strdup(buf); + } config_destroy(&config); } @@ -578,24 +702,26 @@ static void create_domain(int debug, const char *filename) uint32_t domid; libxl_domain_create_info info1; libxl_domain_build_info info2; + libxl_domain_build_state *state; libxl_device_model_info dm_info; libxl_device_disk *disks = NULL; libxl_device_nic *vifs = NULL; libxl_device_pci *pcidevs = NULL; - int num_disks = 0, num_vifs = 0, num_pcidevs = 0; + libxl_device_vfb *vfbs = NULL; + libxl_device_vkb *vkbs = NULL; + libxl_device_console console; + int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs = 0; int i; printf("Parsing config file %s\n", filename); - parse_config_file(filename, &info1, &info2, &disks, &num_disks, &vifs, &num_vifs, &pcidevs, &num_pcidevs, &dm_info); + parse_config_file(filename, &info1, &info2, &disks, &num_disks, &vifs, &num_vifs, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info); if (debug) - printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, pcidevs, num_pcidevs, &dm_info); + printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, pcidevs, num_pcidevs, vfbs, num_vfbs, vkbs, num_vkbs, &dm_info); libxl_ctx_init(&ctx); libxl_ctx_set_log(&ctx, log_callback, NULL); libxl_domain_make(&ctx, &info1, &domid); - libxl_domain_build(&ctx, &info2, domid); - - device_model_info_domid_fixup(&dm_info, domid); + state = libxl_domain_build(&ctx, &info2, domid); for (i = 0; i < num_disks; i++) { disk_info_domid_fixup(disks + i, domid); @@ -605,7 +731,24 @@ static void create_domain(int debug, const char *filename) nic_info_domid_fixup(vifs + i, domid); libxl_device_nic_add(&ctx, domid, &vifs[i]); } - libxl_create_device_model(&ctx, &dm_info, vifs, num_vifs); + if (info1.hvm) { + device_model_info_domid_fixup(&dm_info, domid); + libxl_create_device_model(&ctx, &dm_info, vifs, num_vifs); + } else { + for (i = 0; i < num_vfbs; i++) { + vfb_info_domid_fixup(vfbs + i, domid); + libxl_device_vfb_add(&ctx, domid, &vfbs[i]); + vkb_info_domid_fixup(vkbs + i, domid); + libxl_device_vkb_add(&ctx, domid, &vkbs[i]); + } + init_console_info(&console, 0, state); + console_info_domid_fixup(&console, domid); + if (num_vfbs) + console.constype = CONSTYPE_IOEMU; + libxl_device_console_add(&ctx, domid, &console); + if (num_vfbs) + libxl_create_xenpv_qemu(&ctx, vfbs, 1, &console); + } for (i = 0; i < num_pcidevs; i++) libxl_device_pci_add(&ctx, domid, &pcidevs[i]); libxl_domain_unpause(&ctx, domid); -- 2.30.2